package com.tukez.tmdb.util

/**
 * Work of Mitch Blevins
 * http://cleverlytitled.blogspot.com/2009/03/disjoint-bounded-views-redux.html
 */
class DisjointBoundedView[A, B](val a: Option[A], val b: Option[B])

object DisjointBoundedView {
  type or[A, B] = DisjointBoundedView[A, B]

  private def da[A, B](a: A): or[A, B] = new DisjointBoundedView(Some(a), None)
  private def db[A, B](b: B): or[A, B] = new DisjointBoundedView(None, Some(b))
  private def na[A, B](n: Nothing): or[A, B] = new DisjointBoundedView(None, None)

  implicit def noneToOr2[A, B](n: Nothing): or[A, B] = na(n)
  implicit def aToOr2[A, B](a: A): or[A, B] = da(a)
  implicit def bToOr2[A, B](b: B): or[A, B] = db(b)
  implicit def aToOr3[A, B, C](a: A): or[or[A, B], C] = da(da(a))
  implicit def bToOr3[A, B, C](b: B): or[or[A, B], C] = da(db(b))
  implicit def aToOr4[A, B, C, D](a: A): or[or[or[A, B], C], D] = da(da(da(a)))
  implicit def bToOr4[A, B, C, D](b: B): or[or[or[A, B], C], D] = da(da(db(b)))
  implicit def aToOr5[A, B, C, D, E](a: A): or[or[or[or[A, B], C], D], E] = da(da(da(da(a))))
  implicit def bToOr5[A, B, C, D, E](b: B): or[or[or[or[A, B], C], D], E] = da(da(da(db(b))))
  implicit def aToOr6[A, B, C, D, E, F](a: A): or[or[or[or[or[A, B], C], D], E], F] = da(da(da(da(da(a)))))
  implicit def bToOr6[A, B, C, D, E, F](b: B): or[or[or[or[or[A, B], C], D], E], F] = da(da(da(da(db(b)))))
}  